import "./style-source/carousel.css";
import {Component, OnInit} from "@angular/core";
import {CarouselEffectHTTPService} from "../index/CarouselEffectHTTPService";
import {CarouselImagesInfo} from "../index/CarouselImagesInfo";
import {RequestServerHTTPService} from "../services/RequestServerHTTPService";

@Component({
    selector: "my-carousel",
    templateUrl: "./CarouselTemp.html"
})
export class CarouselEffectComponent implements OnInit {
    private offsetLengthPerSecond = 40;

    public _retrieveImagesUrl = "/positionImage/responseImages.do";
    public target:string = "indexCarousel";
    public carouseImagesInfos:CarouselImagesInfo[];
    public carouseImages:any[];
    public errorMsg:string;

    private startRenderCanvasAnimationId:number;
    private normalStopCanvasTimeoutId:number;

    private carouselCanvas;
    private context2d;
    private currentIndex:number = 0;
    private carouselOffsetX:number = 0;
    private currentImage;
    private nextImage;
    private canvasClientWidth:number;
    private canvasClientHeight:number;

    private normalStopForImages:boolean = false;
    private canvasMouseoverFlag:boolean = false;

    constructor(private _carouselHTTPServer:CarouselEffectHTTPService) {
    }

    ngOnInit() {
        this._carouselHTTPServer.getCarouselImages(this.target, images=> this.retrieveAllImages(images), error=>this.errorMsg);
    }

    private initCanvas() {
        let canvas = <HTMLCanvasElement>document.getElementById("canvas");
        this.carouselCanvas = canvas;
        canvas.width = canvas.clientWidth;
        canvas.height = canvas.clientHeight;
        this.canvasClientWidth = canvas.clientWidth;
        this.canvasClientHeight = canvas.clientHeight;
        this.context2d = canvas.getContext("2d");
        this.currentImage = this.carouseImages[this.currentIndex % this.carouseImages.length];
        this.nextImage = this.carouseImages[++this.currentIndex % this.carouseImages.length];
    }

    private retrieveAllImages(images:CarouselImagesInfo[]) {
        this.carouseImagesInfos = images;
        this.carouseImages = new Array(images.length);
        this.startOnloadImages(0);
    }

    private startOnloadImages(currentIndex:number) {
        if (currentIndex == this.carouseImages.length) {
            this.initCanvas();
            this.startRenderCarouselWithCanvas();
            return;
        }
        let image = new Image(), currentImageInfo = this.carouseImagesInfos[currentIndex];
        image.onload = () => {
            this.carouseImages[currentIndex] = image;
            this.startOnloadImages(++currentIndex);
            image.onload = null;
        };
        image.name = currentImageInfo.imageName;
        image.src = this._retrieveImagesUrl + "?id=" + currentImageInfo.id;
    }

    public startRenderCarouselWithCanvas() {
        if (this.normalStopForImages) {
            this.normalStopForImages = false;
            this.normalStopCanvasTimeoutId = setTimeout(()=>this.startRenderCarouselWithCanvas(), 2000);
        } else {
            this.startRenderCanvasAnimationId = requestAnimationFrame(() => this.startRenderCarouselWithCanvas());
            this.canvasInternalFn();
        }
    }

    private canvasInternalFn() {
        this.drawImageOnCanvas();
        this.carouselOffsetX -= this.offsetLengthPerSecond;
        if ((this.canvasClientWidth + this.carouselOffsetX) <= 0) {
            this.currentImage = this.nextImage;
            this.nextImage = this.carouseImages[(++this.currentIndex % this.carouseImages.length)];
            this.carouselOffsetX = 0;
            this.drawImageOnCanvas();
            this.normalStopForImages = true;
        }
    }

    private drawImageOnCanvas() {
        this.context2d.drawImage(this.currentImage, this.carouselOffsetX, 0, this.canvasClientWidth, this.canvasClientHeight);
        this.context2d.drawImage(this.nextImage, this.canvasClientWidth + this.carouselOffsetX, 0, this.canvasClientWidth, this.canvasClientHeight);
    }
}
